import {Command} from '../constant';
import {Dispatch} from 'typings';
import {IAllReducerProps} from '../types';
import {getReducerData} from '@/redux/store';
import api from 'api';
import Taro from '@tarojs/taro';
import {extraPathsValue} from '@/redux/util';
import {_, UploadImage} from 'wmkit';
import {addressInfo} from '@/utils/location/area/area';
import {Const} from 'config';
import moment from 'dayjs';
import actions from './index';

const urlType = {
  0: 'order-delivery',
  1: 'order-coupon',
  2: 'order-invoice',
  3: 'order-sku-list',
  4: 'order-pay',
};
export default (dispatch: Dispatch) => {
  let action = {
    commonChange(...param: any) {
      dispatch({
        type: Command.commonChange,
        payload: extraPathsValue(...arguments),
      });
    },

    //开关设置查询
    async _switchInit() {
      const {main} = getData();
      const companyInfoIds = main?.stores.map((m) => m.supplier.supplierId);

      await action._invoiceSwitch(companyInfoIds);
    },

    //地址初始化
    async _addressInit() {
      const context = await api.customerDeliveryAddressBaseController.findAddressList();
      let address: any = {};
      let defaltAddress;
      if (context.length) {
        // const defaltAddress = context.filter((item) => item.isDefaltAddress === 1)[0];
        for (let i = 0; i < context.length; i++) {
          const item = context[i];
          const addressInfoStr = await addressInfo(item.provinceId, item.cityId, item.areaId, item.streetId);
          item.addressInfo = addressInfoStr + item.deliveryAddress;
          if (item.isDefaltAddress != 0) {
            defaltAddress = item;
          }
        }
        //没有默认地址取第一个
        address = defaltAddress || context[0];
      }

      // 校验是否需要完善地址
      if (address && address.deliveryAddressId) {
        const result = await api.platformAddressController.verifyAddress({
          provinceId: address.provinceId,
          cityId: address.cityId,
          areaId: address.areaId,
          streetId: address.streetId,
        });
        if (result) {
          address.needComplete = true;
        }
      }
      return address;
    },

    //计算运费
    async _calcFreight() {
      const {stores = [], orderList = {}, localData = {}, grouponFreeDelivery, flashFreeDelivery} =
        getData().main || {};
      const {address = {}} = orderList;
      const {checkGoodsInfos = [], checkCoupon = {}} = localData.confirmCoupon || {};

      if (!address.provinceId) {
        return;
      }

      const consignee = {
        provinceId: address.provinceId,
        cityId: address.cityId,
      };
      const tradeParams = stores.map((st, i) => {
        const amountList = st.discountsPrice;
        let amountTotal = 0;
        if (amountList && amountList.length) {
          amountTotal = amountList.reduce((a, b) => _.add(a, b.amount), 0);
        }
        if (checkCoupon && checkCoupon.couponCodeId) {
          st = st.map((sku) => {
            const checkGoodsInfo = checkGoodsInfos.find((item) => item.get('goodsInfoId') == sku.skuId);
            // 优惠总价追加优惠券金额
            amountTotal = _.add(amountTotal, _.sub(sku.splitPrice, checkGoodsInfo.splitPrice));
            // sku修改为优惠券后的均摊价
            sku.splitPrice = checkGoodsInfo.splitPrice;
            return sku;
          });
        }
        return {
          supplier: {
            storeId: st.supplier.storeId,
            freightTemplateType: st.supplier.freightTemplateType,
          },
          consignee,
          deliverWay: '1',
          tradePrice: {
            totalPrice: _.sub(st.tradePrice.goodsPrice, amountTotal),
          }, //配送方式 0：其他   1：快递
          oldTradeItems: st.tradeItems,
          oldGifts: st.gifts ? st.gifts : [],
        };
      });

      let context = await api.tradeBaseController.getFreight(tradeParams);
      //如果拼团活动是包邮活动
      if (grouponFreeDelivery || flashFreeDelivery) {
        context.map((item) => (item.deliveryPrice = 0));
      }
      await action._changeDeliverFee(context);
    },

    // 修改各店铺运费/应付金额,修改所有订单总运费/总应付金额
    async _changeDeliverFee(freightList) {
      const {stores = [], price = {}} = getData().main || {};

      const totalDeliveryPrice = freightList.reduce((a, b) => _.add(a, b.deliveryPrice), 0);
      stores.map((st, i) => {
        let discountsTotalPrice = 0;
        const discountsPriceList = st.discountsPrice;
        if (discountsPriceList && discountsPriceList.length) {
          discountsTotalPrice = discountsPriceList.reduce((a, b) => _.add(a, b.amount), 0);
        }
        const deliveryPrice = freightList[i].deliveryPrice;
        st.tradePrice.deliveryPrice = deliveryPrice;
        st.tradePrice.totalPrice = _.add(_.sub(st.tradePrice.goodsPrice, discountsTotalPrice), deliveryPrice);
        return st;
      });

      const totalPrice = _.sub(
        _.add(_.sub(price.goodsTotalPrice, price.discountsTotalPrice), totalDeliveryPrice),
        price.pointTotalPrice,
      );

      action.commonChange([
        {paths: 'main.stores', value: stores},
        {paths: 'main.price.totalPrice', value: totalPrice},
        {paths: 'main.price.totalDeliveryPrice', value: totalDeliveryPrice},
      ]);
    },

    //上传图片
    async _chooseImage(storeId) {
      //选择图片后 会触发didshow函数
      await action._savaLocal();
      const FILE_MAX_SIZE = 500 * 1024 * 10;
      const {context} = await UploadImage(FILE_MAX_SIZE);
      dispatch({
        type: Command.commonChange,
        payload: {
          paths: 'main.orderList.enclosures',
          value: (enclosures) => {
            const bool = enclosures[storeId] && enclosures[storeId].length;
            bool ? enclosures[storeId].push(context[0]) : (enclosures[storeId] = [context[0]]);
            return enclosures;
          },
        },
      });
    },

    //删除图片
    async _deleteImage(storeId, key) {
      dispatch({
        type: Command.commonChange,
        payload: {
          paths: 'main.orderList.enclosures',
          value: (enclosures) => {
            enclosures[storeId].splice(key, 1);
          },
        },
      });
    },

    //订单备注修改
    _orderBuyRemarkChange(storeId, val) {
      dispatch({
        type: Command.commonChange,
        payload: {
          paths: 'main.orderList.buyRemark',
          value: (buyRemark) => {
            buyRemark[storeId] = val;
          },
        },
      });
    },

    //查询发票开关并初始化
    async _invoiceSwitch(companyInfoIds) {
      const context = companyInfoIds?.length
        ? await api.invoiceProjectBaseController.queryProjectSwitchByIds({companyInfoIds})
        : [];
      const invoiceData = context.reduce((a, {companyInfoId, supportInvoice}) => {
        a[companyInfoId.toString()] = {
          supportInvoice,
          commonCheck: {
            invoiceProject: '',
            invoiceProjectName: '',
          },
        };
        return a;
      }, {});
      action.commonChange('main.orderList.invoiceData', invoiceData);
    },

    //积分初始化
    async _pointInit() {
      Promise.all([
        await api.customerBaseController.findCustomerCenterInfo(),
        await api.systemPointsConfigController.query(),
      ])
        .then(([one, two]) => {
          action.commonChange([
            {paths: 'main.points.totalPoint', value: one.pointsAvailable},
            {paths: 'main.points.pointConfig', value: two},
          ]);
        })
        .then(async () => {
          await action._maxPointCal();
        });
    },

    //计算积分可抵扣最大
    async _maxPointCal() {
      const {
        main: {
          price: {goodsTotalPrice, discountsTotalPrice, pointTotalPrice, totalDeliveryPrice},
          points: {totalPoint, pointConfig},
        },
      } = getData();
      let totalPrice = _.sub(goodsTotalPrice, discountsTotalPrice);
      if (totalPoint <= 0) return;
      // 最大积分
      let maxPoint = 0;

      // 当前用户的总积分
      let mePoint = totalPoint;
      //  积分转换单位，即多少积分抵扣1元
      let pointWorth = pointConfig.pointsWorth;
      let limitPercent = _.div(pointConfig.maxDeductionRate, 100);
      //  积分使用最高限额
      let limitPrice = _.mul(totalPrice, limitPercent);

      // 如果积分价值设置了，则计算当前积分可以抵扣多少金额
      if (pointWorth != null) {
        // 当前订单值多少积分，比如订单金额为10元，10积分=1元，则buyPoint = 100积分
        let buyPoint = Math.floor(_.mul(limitPrice, pointWorth));
        // 比较二方积分，以最少的为准
        if (buyPoint > mePoint) {
          maxPoint = mePoint;
        } else {
          maxPoint = buyPoint;
        }
      }
      await action.commonChange('main.points.maxPoint', maxPoint);
    },

    async _savaLocal() {
      const {
        main: {
          orderList: {invoiceData, address},
          localData: {deliverType, confirmCoupon},
          openGroupon,
        },
      } = getData();

      //发票缓存
      await Taro.setStorageSync('mini::invoice', invoiceData);
      //优惠券缓存处理
      await action._couponLocal();
      //支付方式缓存处理
      await Taro.setStorageSync('mini::deliveryType', deliverType);
      //地址缓存
      await Taro.setStorageSync('mini::confirmAddress', address);
      //地址缓存
      await Taro.setStorageSync('mini::openGroupon', openGroupon);
    },

    //跳转页面
    async _urlChange(type: 0 | 1 | 2 | 3 | 4 | 5, param) {
      //线上支付不需要存
      if (type === 4) {
        await Taro.redirectTo({url: `/pages/package-C/order/order-tool/${urlType[type]}/index?param=${param}`});
        return;
      }

      if (type === 5) {
        //单个商家商品点击进入商品详情页
        await Taro.navigateTo({url: `/pages/package-B/goods/goods-details/index?skuId=${param.skuId}`});
        return;
      }
      await action._savaLocal();
      await Taro.navigateTo({url: `/pages/package-C/order/order-tool/${urlType[type]}/index?param=${param}`});
    },

    //优惠券缓存处理
    async _couponLocal() {
      const {
        main: {
          coupons,
          useStatus: {selectCoupon},
          stores,
          localData: {confirmCoupon},
        },
      } = getData();
      const storeIds = stores.map((item) => item.supplier.storeId);
      //查询优惠券的字段
      await Taro.setStorageSync('mini::orderCoupon', {coupons, selectCoupon, storeIds});
      //选中的优惠券
      await Taro.setStorageSync('mini::checkCoupon', confirmCoupon.checkCoupon);
      //优惠券折扣
      await Taro.setStorageSync('mini::confirmCoupon', confirmCoupon);
    },

    async _clearLocal() {
      await Taro.removeStorageSync('mini::deliveryType');
      await Taro.removeStorageSync('mini::confirmCoupon');
      await Taro.removeStorageSync('mini::orderCoupon');
      await Taro.removeStorageSync('mini::checkCoupon');
      await Taro.removeStorageSync('mini::invoice');
      await Taro.removeStorageSync('mini::confirmAddress');
      await Taro.removeStorageSync('mini::openGroupon');
    },

    async _getLoacl() {
      const deliverType = (await Taro.getStorageSync('mini::deliveryType')) || 0;
      const confirmCoupon = (await Taro.getStorageSync('mini::confirmCoupon')) || {};
      const checkCoupon = (await Taro.getStorageSync('mini::checkCoupon')) || {};
      const invoiceData = await Taro.getStorageSync('mini::invoice');
      let address = await Taro.getStorageSync('mini::confirmAddress');
      if (address && address.deliveryAddressId) {
        address.addressInfo = await addressInfo(address.provinceId, address.cityId, address.areaId, address.streetId);
      }
      await action.commonChange([
        {paths: 'main.localData.deliverType', value: deliverType},
        {paths: 'main.localData.confirmCoupon', value: confirmCoupon},
        {paths: 'main.localData.checkCoupon', value: checkCoupon},
        {paths: 'main.orderList.invoiceData', value: invoiceData},
        {paths: 'main.orderList.address', value: address},
      ]);

      // await action._clearLocal();
    },

    async _confirmMaskInit(e) {
      const mask = await action._getMasK(e.code, e.message);
      await action.commonChange('main.mask', mask);
    },

    // 校验是否是四级地址
    async isTrueAddress(address) {
      if (address) {
        const result = await api.platformAddressController.verifyAddress({
          provinceId: address.provinceId,
          cityId: address.cityId,
          areaId: address.areaId,
          streetId: address.streetId,
        });
        if (result) {
          action.commonChange('main.visible', true);
          return true;
        }
      }
    },

    //提交订单
    async _submit(forceCommit) {
      const {
        main: {
          points: {usePoint},
          localData: {
            deliverType,
            confirmCoupon: {checkCoupon},
          },
          orderList: {enclosures, address, invoiceData, buyRemark},
          stores,
        },
      } = getData();

      if (!address.deliveryAddressId) {
        await action._showToast('请选择收货地址');
        return;
      }
      // 校验是否需要完善地址
      if (address && address.deliveryAddressId) {
        let flag = await this.isTrueAddress(address);
        if (flag) {
          return false;
        }
      }

      const {provinceId, cityId, areaId, streetId, deliveryAddress} = address;
      const addrDetail = (await addressInfo(provinceId, cityId, areaId, streetId)) + deliveryAddress;

      let storeCommitInfoList = [];
      await Promise.all(
        stores.map(async (o, i) => {
          const storeId = o.supplier.storeId,
            supplierId = o.supplier.supplierId;
          const thisInvoice = invoiceData[supplierId];
          const invoiceAddress = invoiceData[supplierId].invoiceAddress;
          const commonCheck = invoiceData[supplierId].commonCheck;
          //是否单独的收货地址
          const sperator = Boolean(thisInvoice.invoiceAddress && thisInvoice.invoiceAddress.deliveryAddressId);

          /* 本地存储的格式为 1:不需要发票 2:普通发票 3:增值发票 0:不支持发票
           开票类型，必传 0：普通发票 1：增值税专用发票 -1：无 */

          //若果为-2 置为-1
          const invoiceType = thisInvoice.supportInvoice - 2 === -2 ? -1 : thisInvoice.supportInvoice - 2;

          //店铺备注
          const remark = buyRemark[storeId] ? buyRemark[storeId] : '';

          //图片附件
          const enclosuresOrder = enclosures[storeId];

          const invoiceAddrDetail = invoiceAddress
            ? (await addressInfo(
                invoiceAddress.provinceId,
                invoiceAddress.cityId,
                invoiceAddress.areaId,
                invoiceAddress.streetId || '',
              )) + invoiceAddress.deliveryAddress
            : '';
          storeCommitInfoList.push({
            storeId: o.supplier.storeId, // 店铺Id
            payType: deliverType, //支付类型，必传
            invoiceType,
            generalInvoice:
              invoiceType == 0
                ? {
                    flag: commonCheck.invoiceType, //0:个人 1:单位
                    title: commonCheck.invoiceTitle, //发票抬头
                    identification: commonCheck.invoiceIdentification, //纳税人识别号
                  }
                : {}, //普通发票与增票参数至少一项必传
            specialInvoice:
              invoiceType == 1
                ? {
                    id: thisInvoice.customerInvoiceResponse.customerInvoiceId,
                  }
                : {}, //增值税专用发票与普票至少一项必传
            specialInvoiceAddress: Boolean(invoiceAddress && thisInvoice.invoiceAddress.deliveryAddressId), //是否单独的收货地址
            invoiceAddressId:
              invoiceType !== -1 && sperator ? invoiceAddress.deliveryAddressId : address.deliveryAddressId, //发票的收货地址ID,必传

            invoiceAddressDetail: invoiceType !== -1 && sperator ? invoiceAddrDetail : deliveryAddress, //收货地址详细信息（不包含省市区）

            invoiceAddressUpdateTime:
              invoiceType !== -1 && sperator
                ? invoiceAddress && invoiceAddress.updateTime
                  ? moment(invoiceAddress.updateTime).format(Const.SECONDS_FORMAT)
                  : null
                : address && address.updateTime
                ? moment(address.updateTime).format(Const.SECONDS_FORMAT)
                : null,

            invoiceProjectId: invoiceType !== -1 ? commonCheck.invoiceProject : null, //开票项目id，必传
            invoiceProjectName: invoiceType !== -1 ? commonCheck.invoiceProjectName : '', //开票项目名称，必传

            invoiceProjectUpdateTime:
              invoiceAddress && invoiceAddress.projectUpdateTime
                ? moment(invoiceAddress.projectUpdateTime).format(Const.SECONDS_FORMAT)
                : null, //开票项目修改时间

            buyerRemark: remark, //订单备注
            encloses: enclosuresOrder ? enclosuresOrder.join(',') : '',
            deliverWay: deliverType, //配送方式，默认快递
            couponCodeId:
              checkCoupon && o.supplier.storeId === checkCoupon.storeId && checkCoupon.couponCodeId
                ? checkCoupon.couponCodeId
                : null, // 选择的店铺优惠券id
          });
        }),
      );

      const params = {
        consigneeId: address.deliveryAddressId,
        consigneeAddress: addrDetail,
        consigneeUpdateTime: address.updateTime ? moment(address.updateTime).format(Const.SECONDS_FORMAT) : null,
        storeCommitInfoList,
        commonCodeId:
          checkCoupon && checkCoupon.storeId === -1 && checkCoupon.couponCodeId ? checkCoupon.couponCodeId : null,
        orderSource: Taro.getEnv() === 'WEAPP' ? 'LITTLEPROGRAM' : 'WECHAT', // 需要校验营销活动,
        forceCommit,
        isFlashSaleGoods: true,
        //TODO shareUserId
        // shareUserId: getShareUserId()
      };
      if (_.sub(usePoint, 0) > 0) {
        params['points'] = usePoint;
      }

      let context;
      try {
        context = await api.tradeBaseController.commit(params);
        let stringContext = JSON.stringify(context);
        // 0元订单直接支付
        const totalPrice = context.map((i) => i.price).reduce((a, b) => a + b, 0);
        if (stores[0].tradeItems[0].isFlashSaleGoods && stores[0].tradeItems[0].flashSaleGoodsId) {
          await api.flashSaleController.delFlashSaleGoodsQualifications({
            flashSaleGoodsId: stores[0].tradeItems[0].flashSaleGoodsId,
          });
        }
        if (totalPrice == 0) {
          // 0元订单且订单审核状态为不需要审核时直接跳转支付成功页
          let directPayFlag = context && context[0].tradeState.auditState == 'CHECKED';
          if (directPayFlag) {
            try {
              await api.payBaseController.defaultPayBatch({tradeIds: context.map((item) => item.tid)});
              await Taro.redirectTo({
                url: `/pages/package-C/order/order-tool/order-success/index?param=${stringContext}`,
              });
              return;
            } catch (e) {
              await action._showToast(e.message);
            }
          }
        }

        let directPayFlag = true;
        if (deliverType === 0 && context && context.length > 0) {
          for (let i = 0; i < context.length; i++) {
            if (context[i].tradeState.auditState !== 'CHECKED' || context[i].paymentOrder !== 'PAY_FIRST') {
              directPayFlag = false;
              break;
            }
          }
          if (directPayFlag) {
            await action._clearLocal();
            await action._urlChange(4, JSON.stringify(context));
            return;
          }
        }
        //前面条件都不符合 因为开启了订单审核
        context.isExamine = true;
        await Taro.redirectTo({
          url: `/pages/package-C/order/order-tool/order-success/index?param=${stringContext}&isExamine=true`,
        });
      } catch (e) {
        await action._confirmMaskInit(e);
      }
    },

    //错误提示框
    async _getMasK(code, message) {
      let mask = {};
      switch (code) {
        case 'K-999999':
          mask = {
            isOpen: true,
            title: '优惠失效提醒',
            content: message,
            confirmText: '重新下单',
            cancelText: '继续下单',
            onClose: async () => {
              await action.commonChange('main.mask.isOpen', false);
            },
            onConfirm: async () => {
              await action.commonChange('main.mask.isOpen', false);
              await action._submit(true);
            },
          };
          break;
        case 'K-080301':
          mask = {
            isOpen: true,
            title: '',
            content: '很抱歉，商品已失效，请重新选择',
            confirmText: '确定',
            cancelText: '',
            onClose: async () => {},
            onConfirm: async () => {
              await action.commonChange('main.mask.isOpen', false);
              await Taro.navigateTo({url: '/pages/package-S/shop-cart/index'});
            },
          };
          break;
        case 'K-080302':
          mask = {
            isOpen: true,
            title: '',
            content: '很抱歉，商品已失效，请重新选择',
            confirmText: '确定',
            cancelText: '',
            onClose: async () => {},
            onConfirm: async () => {
              await action.commonChange('main.mask.isOpen', false);
              await Taro.navigateTo({url: '/pages/package-S/shop-cart/index'});
            },
          };
          break;
        case 'K-010208':
          mask = {
            isOpen: true,
            title: '',
            content: '当前积分不足',
            confirmText: '确定',
            cancelText: '',
            onClose: async () => {},
            onConfirm: async () => {
              await action.commonChange('main.mask.isOpen', false);
              await Taro.startPullDownRefresh;
              await actions(dispatch).actions.init();
            },
          };
          break;
        default:
          mask = {
            isOpen: true,
            title: '',
            content: message,
            confirmText: '确定',
            cancelText: '',
            onClose: async () => {},
            onConfirm: async () => {
              await action.commonChange('main.mask.isOpen', false);
              await Taro.navigateTo({url: '/pages/package-S/shop-cart/index'});
            },
          };
      }
      return mask;
    },

    async _showToast(title) {
      await Taro.showToast({
        title,
        icon: 'none',
        duration: 2000,
      });
    },

    //通过积分算对应的金额
    _pointToMoney(point) {
      const {
        main: {
          points: { pointConfig },
        },
      } = getData();

      return _.div(point, pointConfig.pointsWorth);
    },

  };
  return action;
};

function getData(): IAllReducerProps {
  return {
    main: getReducerData('packageCOrderOrderConfirmMain'),
  };
}

//create by moon https://github.com/creasy2010/moon
